import { asyncRouterMap, constantRouterMap } from '@/router/index';
/* Layout */
import Layout from '../../views/layout/Layout'

//判断是否有权限访问该菜单
function hasPermission(menus, route) {
  ////如果路由有name，则比较路由和菜单信息，修改路由数据
  if (route.name) {
    ////找到和name匹配的菜单项数据
    let currMenu = getMenu(route.name, menus);
    ////如果找到了匹配的菜单项
    if (currMenu != null) {
      //设置菜单的标题、图标和可见性
      ////1/修改路由的标题为菜单项设置的标题
      if (currMenu.title != null && currMenu.title !== '') {
        route.meta.title = currMenu.title;
      }
      ////2/修改路由的图标为菜单项设置的图标
      if (currMenu.icon != null && currMenu.title !== '') {
        route.meta.icon = currMenu.icon;
      }
      ////3/路由菜单是否隐藏由菜单数据来决定
      if (currMenu.hidden != null) {
        route.hidden = currMenu.hidden !== 0;
      }
      ////4/修改路由菜单项的排序为后台设定好的顺序
      if (currMenu.sort != null && currMenu.sort !== '') {
        route.sort = currMenu.sort;
      }
      return true;
      ////如果没有找到匹配的菜单项...
    } else {
      ////将排到最前边
      route.sort = 0;
      ////如果路由的隐藏属性已经定已过，且设置为隐藏,通过检查，否则不通过
      if (route.hidden !== undefined && route.hidden === true) {
        return true;
      } else {
        return false;
      }
    }
    ////如果路由没有name，则不用再进行权限检查，直接放行
  } else {
    return true
  }
}

//根据路由名称获取菜单
function getMenu(name, menus) {
  for (let i = 0; i < menus.length; i++) {
    let menu = menus[i];
    ////名称匹配就算找到
    if (name === menu.name) {
      return menu;
    }
  }
  return null;
}

//对菜单进行排序
function sortRouters(accessedRouters) {
  for (let i = 0; i < accessedRouters.length; i++) {
    let router = accessedRouters[i];
    if (router.children && router.children.length > 0) {
      router.children.sort(compare("sort"));
    }
  }
  accessedRouters.sort(compare("sort"));
}

//降序比较函数
function compare(p) {
  return function (m, n) {
    let a = m[p];
    let b = n[p];
    return b - a;
  }
}

/**
 * 过滤前端预设好的动态路由
 * 通过后台获取过滤条件，对前端设置好的路由进行过滤
 * @param {*} data
 */
function filteAsyncRouterMap(menus) {
  ////根据菜单资源数据，过滤预设的路由
  const accessedRouters = asyncRouterMap.filter(router => {
    //admin帐号直接返回所有菜单
    // if(username==='admin') return true;
    ////如果权限检查通过了
    if (hasPermission(menus, router)) {
      ////再检查路由的子路由部分
      if (router.children && router.children.length > 0) {
        router.children = router.children.filter(child => {
          if (hasPermission(menus, child)) {
            return child
          }
          return false;
        });
        return router
      } else {
        return router
      }
    }
    ////权限检查都没有通过的，被过滤掉
    return false;
  });
  return accessedRouters;
}
/**
* 后台查询的菜单数据拼装成路由格式的数据
* 由后端提供生成路由的数据，前端根据规律直接生成动态路由，不需要权限验证，也不需要预设路由，但是要准备好页面和图标资源
* @param routes
*/
function generaMenu(routers, data) {
  //console.log(JSON.stringify(data));
  data.forEach(item => {
    // alert(JSON.stringify(item))
    const menu = {
      path: item.path,
      component: item.url === '#' ? Layout : () => import(`@/views${item.url}/index`),
      redirect: item.redirect === '#' ? null : item.redirect,
      // hidden: true,
      children: [],
      name: item.name,
      meta: { title: item.title, icon: item.icon, roles: item.roles }
    }
    if (item.children) {
      generaMenu(menu.children, item.children)
    }
    routers.push(menu)
  })
}

const permission = {
  state: {
    routers: constantRouterMap,
    addRouters: []
  },
  mutations: {
    SET_ROUTERS: (state, routers) => {
      state.addRouters = routers;
      ////将静态路由资源和动态路由资源合并
      state.routers = constantRouterMap.concat(routers);
      ////console.log(JSON.stringify(state.routers));
    },
    ////这个操作，是多种途径构建路由，将静态路由和多次动态路由拼接起来
    ADD_ROUTERS: (state, routers) => {
      if (state.addRouters && state.addRouters.length > 0) {
        state.addRouters = state.addRouters.concat(routers);
      } else {
        state.addRouters = routers;
      }
      ////将静态路由资源和动态路由资源合并
      ////console.log(state.routers);
      if (state.routers && state.routers.length > 0) {
        state.routers = state.routers.concat(routers);
      } else {
        state.routers = constantRouterMap.concat(routers);
      }

    }
  },
  actions: {
    //下面这个调用是在src/permission.js中store.dispatch('GenerateRoutes', { menus, username }).then(() => { 这一行
    GenerateRoutes({ commit }, data) {
      return new Promise(resolve => {
        const { menus } = data;
        const { menuInfos } = data;
        ////根据菜单资源数据，过滤预设的路由
        const accessedRouters = filteAsyncRouterMap(menus);
        ////根据后端返回数据构建路由，形成可访问的菜单
        generaMenu(accessedRouters, menuInfos);
        //对菜单进行排序
        sortRouters(accessedRouters);
        ////将过滤处理合格的路由添加到路由清单
        ////commit('SET_ROUTERS', accessedRouters);
        commit('SET_ROUTERS', accessedRouters);
        resolve();
      })
    },
  }

};

export default permission;

